/*******************************************
 * Copyright 2007 Aphrodite Framework for javaME .
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * Email : owner@aphroditeme.dev.java.net
 * Contributors:
 *     Kent Elton - initial API and implementation
 *******************************************/

package com.aphrodite.ui.schema;

import java.util.Vector;

import javax.microedition.lcdui.Image;

/**
 * <p>
 * Schema for for a Tree widget
 * </p>
 * 
 * 
 * @author kentelt
 * 
 */
public class TreeNode {

	/**
	 * Caption of the node
	 */
	public String caption = null;

	/**
	 * Vector to store the children
	 */
	private Vector children = null;

	/**
	 *Image of the node
	 */
	public Image image = null;

	/**
	 * index of the child node
	 */
	private int index = 0;

	/**
	 * Is node Expanded
	 */
	public boolean isExpanded = false;

	/**
	 * Parent node
	 */
	private TreeNode parentNode = null;

	/* graphic properties to position the node */
	public int x = 0;

	public int y = 0;

	/* node properties */

	public TreeNode(Object caption) {
		this(caption, null);
	}

	/**
	 * @param image
	 *            to be used for the tree node. If null no image is used.
	 * @param caption
	 *            for the node(toString() of the passed object is used)
	 * 
	 */
	public TreeNode(Object caption, Image image) {
		this.caption = caption.toString();
		this.image = image;
		this.children = new Vector();
	}

	/*
	 * Used to append the child nodes
	 */
	public void addChild(TreeNode node) {
		node.parentNode = this;
		node.index = this.children.size();
		this.children.addElement(node);
	}

	// /**
	// * collapse the parent node
	// */
	public void collapse() {
		this.isExpanded = false;
	}

	public void deleteChildren() {
		this.children.removeAllElements();
	}

	/**
	 * expand the parent node
	 */
	public void expand() {
		if (this.children.size() > 0) {
			this.isExpanded = true;
		}
	}

	// public String getCaption() {
	// return caption;
	// }
	// public Image getNodeImage() {
	// return image;
	// }

	/**
	 * Get Child node
	 * 
	 * @param index
	 *            Index of child node
	 * @return Child node
	 */
	public TreeNode getChild(int index) {
		if (index >= 0 && index < this.children.size()) {
			return (TreeNode) this.children.elementAt(index);
		}
		return null;
	}

	/**
	 * Get children size
	 * 
	 * @return childrenSize
	 */
	public int getChildrenNum() {
		return this.children.size();
	}

	/**
	 * Get Last Child
	 * 
	 * @return Last Menu node
	 */
	public TreeNode getLastChild() {
		return getChild(this.children.size() - 1);
	}

	/**
	 * Get Next Sibiling
	 * 
	 * @return Next Sibling node
	 */
	public TreeNode getNextSibling() {
		if (parentNode != null) {
			return parentNode.getChild(index + 1);
		}
		return null;
	}

	public TreeNode getParent() {
		return parentNode;
	}

	// public boolean isExpanded() {
	// return isExpanded;
	// }

	/**
	 * Get Previous Sibling
	 * 
	 * @return Prev Sibling node
	 */
	public TreeNode getPrevSibling() {
		if (parentNode != null) {
			return parentNode.getChild(index - 1);
		}
		return null;
	}

	/**
	 * Is menu node has Childrens
	 * 
	 * @return true/false
	 */
	public boolean hasChildren() {
		return this.children.size() > 0;
	}

	/**
	 * remove child
	 * 
	 * @param index
	 *            Index of the child element
	 */
	public void removeChild(int index) {
		this.children.removeElementAt(index);
		for (int i = index; i < this.children.size(); i++) {
			this.getChild(i).index--;
		}
	}

	/**
	 * This method is used to set the Node
	 */
	public void setNode(int index, TreeNode menuNode) {
		if (this.children.size() > index && index >= 0) {
			menuNode.parentNode = this;
			menuNode.index = index;
			this.children.setElementAt(menuNode, index);
		} else {
			throw new IllegalArgumentException("Index is outside of the range");
		}
	}

}
